package cn.snorlaxzjt.LBSserver.service;

import cn.snorlaxzjt.LBSserver.mapper.FriendsMapper;
import cn.snorlaxzjt.LBSserver.mapper.MomentRepo;
import cn.snorlaxzjt.LBSserver.mapper.UserMapper;
import cn.snorlaxzjt.LBSserver.po.body.MomentSelectBody;
import cn.snorlaxzjt.LBSserver.po.entity.Moment;
import cn.snorlaxzjt.LBSserver.po.entity.MomentEntity;
import cn.snorlaxzjt.LBSserver.po.entity.User;
import cn.snorlaxzjt.LBSserver.po.page.ResultPage;
import javax.annotation.Resource;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Transactional(rollbackFor = RuntimeException.class)
@Slf4j
@Service
public class MomentService
{
    @Resource
    private MomentRepo momentRepo;

    @Resource
    private FriendsMapper friendsMapper;

    @Resource
    private UserMapper userMapper;

    /**
     * 通过用户id 查询朋友圈
     *
     * @param body
     * @return
     */
    public ResultPage<List<Moment>> queryMomentsByUserId(MomentSelectBody body)
    {
        User u = userMapper.findUserById(body.getUserId());
        if(body.getCurId() == -1){
            body.setCurId(Integer.MAX_VALUE);
        }
        ResultPage<List<Moment>> resultPage = new ResultPage<>();
        List<Moment> list = momentRepo.queryMomentsByUserId(body.getUserId(), body.getSize(),body.getCurId());
        resultPage.setItems(list.stream().peek(i-> {
            i.setUserId(u.getId());
            i.setUsername(u.getUsername());
            i.setAvatar(u.getAvatar());
        }).collect(Collectors.toList()));
        resultPage.setCount(momentRepo.queryCountByUserId(body.getUserId()));
        resultPage.setCurId(list.get(list.size()-1).getId());
        resultPage.setSize(body.getSize());
        return resultPage;
    }

    /**
     * 通过用户id 通过用户id查询所有好友朋友圈
     *
     * @param body
     * @return
     */
    public ResultPage<List<Moment>> queryFriendsMoments(MomentSelectBody body)
    {

        ResultPage<List<Moment>> resultPage = new ResultPage<>();

        if(body.getCurId() == -1){
            body.setCurId(Integer.MAX_VALUE);
        }

        //get所有朋友的id
        //TODO 可以替换为从Redis获取朋友List，第一次调用记录进，有效期为一天
        List<Integer> friends = friendsMapper.getFriendsById(body.getUserId());

        //get一页的moments
        List<Moment> list = momentRepo.queryFriendsMomentsById(friends, body.getSize(),body.getCurId());
        resultPage.setCount(momentRepo.queryFriendsMomentsCountById(friends));

        //查询用户信息
        list = fillUserInfoOfMoments(list);
        if(list.size()>0) {
            resultPage.setCurId(list.get(list.size() - 1).getId());
        }else {
            resultPage.setCurId(0L);
        }
        resultPage.setSize(body.getSize());
        resultPage.setItems(list);
        return resultPage;
    }

    public List<Moment> fillUserInfoOfMoments(List<Moment> list){
        if(list == null || list.size() == 0)return new ArrayList<>();
        Set<Integer> idSet = list.stream().map(Moment::getUserId).collect(Collectors.toSet());
        List<User> userInfoList = userMapper.selectBatchIds(new ArrayList<>(idSet));
        HashMap<Integer,User> hashMap = (HashMap<Integer, User>) userInfoList.stream().collect(Collectors.toMap(User::getId, Function.identity()));
        list = list.stream().peek(m->{
            User u = hashMap.get(m.getUserId());
            m.setAvatar(u.getAvatar());
            m.setUsername(u.getUsername());
        }).collect(Collectors.toList());
        return list;
    }


    public void save(MomentEntity body)
    {
        momentRepo.insert(body);
    }

    public Integer del(Integer id)
    {
        return  momentRepo.deleteById(id);
    }

    public List<Moment> queryMomentsInDis(BigDecimal lon, BigDecimal lat, Double distance){
        List<Moment> list =  momentRepo.queryMomentsInDis(lon,lat,distance);
        return fillUserInfoOfMoments(list);
    }

    public List<String> getRecentlyThreeImgById(Integer id){
        return momentRepo.getRecentlyThreeById(id);
    }

}
